import logging
import random,string
import django_redis
from captcha.image import ImageCaptcha
from django.http import HttpResponse, JsonResponse
from django.views import View
from django_redis import get_redis_connection

logger = logging.getLogger('django')

class ImgCodeView(View):
    def get(self,request,uuid):
        '''
        获取图片验证码资源
        :param request:
        :return:
        '''
        # 随机生成四位数值类型验证码
        seed = string.digits  # 生成0-9字符串
        r = random.choices(seed,k=4)  # 生成的是列表['2','3','1','5']
        imgcode_str = ''.join(r)  # '2315'

        # 根据生成的数字创建图片验证码资源
        imgcode = ImageCaptcha().generate(chars=imgcode_str)

        # 将imgcode_str存入redis数据库
        redis_conn = get_redis_connection('verify_code')
        redis_conn.setex('img_%s'%uuid,300,imgcode_str)

        # 返回资源给前端
        return HttpResponse(imgcode,content_type='image/png')


class SmsCodeView(View):
    def get(self,request,phone):
        '''
        匹配并删除图形验证码，发送验证码
        :param request:
        :param phone:
        :return:
        '''
        # 获取请求参数（路径参数+查询字符串）
        imgcode_client = request.GET.get('imgcode','')  # 用户输入的图形验证码
        uuid = request.GET.get('uuid','').replace('/','')  # 真正的验证码
        print('uuid是',uuid)

        # 校验参数(完整性判断)
        if not all([phone,imgcode_client,uuid]):
            return JsonResponse({'code': '4001','errormsg':'请表单填写完整！'})

        # 建立redis数据库连接
        redis_conn = get_redis_connection('verify_code')


        # 获取is_send的值并且判断是否过于频繁发送验证码
        is_send = redis_conn.get('is_send_%s'%phone)
        if is_send:
            return JsonResponse({'code': '4004','errormsg':'发送短信验证码过于频繁！'})

        # 获取服务器端生成的图片验证码
        imgcode_server = redis_conn.get("img_%s"%uuid)

        # 匹配（非空判断/一致性判断）
        if imgcode_server is None:
            return JsonResponse({'code':'4002','errormsg':'图片验证码已过期'})

        if imgcode_client.lower() != imgcode_server.decode('utf-8').lower():  # 服务器端是byte类型 转成字符串 再转成小写
            return JsonResponse({'code':'4003','errormsg':'图片验证码不一致！'})

        # 删除图片验证码（避免用户恶意测试）
        try:
            redis_conn.delete('img_%s'%uuid)
        except Exception as e:
            logger.error(e)

        # 生成短信验证码(6位数字)
        seed = string.digits
        r= random.choices(seed,k=6)
        smscode_str = ''.join(r)
        print('短信验证码为：',smscode_str)
        # 保存短信验证码到redis数据库,并保存标记变量is_send 防止平凡发送短信验证码
        # redis_conn.setex('sms_%s'%phone,60,smscode_str)
        # redis_conn.setex('is_send_%s'%phone,60,1)

        '''
        批量 获取/发送管道对象
        '''
        pl = redis_conn.pipeline()
        pl.setex('sms_%s'%phone,60,smscode_str)
        pl.setex('is_send_%s'%phone,60,1)
        pl.execute()

        # 发送短信验证码
        # ret = sms3.send_sms_code(smscode_str,phone)

        # 根据外部接口返回值响应前端结果
        # if ret.get('code') == 2:
        #     return JsonResponse({'code':'200','errormsg':'ok'})
        # return JsonResponse({'code':'5001','errormsg':'发送短信验证码错误！'})

        '''
        异步执行 发送短信验证码
        '''
        from mgproject.celery_tasks.sms.tasks import huyi_send_sms_code
        # Celery异步发送短信验证码
        ret = huyi_send_sms_code.delay(phone,smscode_str)  # delay异步

        # 根据外部接口返回值响应前端结果
        if ret:  # 执行一个任务就返回一个taskid 像uuid一样的
            return JsonResponse({'code':'200','errormsg':'ok'})
        return JsonResponse({'code':'5001','errormsg':'发送短信验证码错误'})

class CheckSmsCode(View):
    def get(self,request,phone):
        '''
        用户注册时短信验证码校验
        :param request:
        :param phone:
        :return:
        '''
        # 接受请求参数
        smscode_client = request.GET.get('smscode','')

        # 校验匹配
        if not all([phone,smscode_client]):
            return JsonResponse({'code':'4001','errormsg':'缺少必传参数'})

        # 查询服务器端短信验证码
        redis_conn = django_redis.get_redis_connection('verify_code')
        smscode_server = redis_conn.get('sms_%s'%phone)

        # 匹配(非空判断/有效性判断)
        if smscode_server is None:
            return JsonResponse({'code':'4002','errormsg':'短信验证码失效'})

        if smscode_client != smscode_server:  # 服务器端是byte类型 转成字符串 再转成小写
            return JsonResponse({'code': '4003', 'errormsg': '短信验证码不一致！'})

        # 响应结果
        return JsonResponse({'code':'200','errormsg':'ok'})